<?php

/**
 * Texy! universal text -> html converter
 * --------------------------------------
 *
 * This source file is subject to the GNU GPL license.
 *
 * @link       http://www.texy.info/
 * @author     David Grudl aka -dgx- <dave@dgx.cz>
 * @copyright  Copyright (c) 2004-2006 David Grudl
 * @license    GNU GENERAL PUBLIC LICENSE
 * @package    Texy
 * @category   Text
 * @version    1.0 for PHP4 & PHP5 (released 2006/04/18)
 */


/**
 * Converts all HTML entities to their applicable characters (PHP4 version)
 *
 * Enhanced alternative to html_entity_decode:
 *   - support for UTF-8 & WINDOWS-1250 on PHP4
 *   - support for entity &apos;
 */
class TexyHtmlEntity
{
    var
        // translate table 'named entity' => unicode ordinal
        $entity_to_unicode = array('AElig'=>198,'Aacute'=>193,'Acirc'=>194,'Agrave'=>192,'Alpha'=>913,'Aring'=>197,'Atilde'=>195,'Auml'=>196,'Beta'=>914,
            'Ccedil'=>199,'Chi'=>935,'Dagger'=>8225,'Delta'=>916,'ETH'=>208,'Eacute'=>201,'Ecirc'=>202,'Egrave'=>200,'Epsilon'=>917,'Eta'=>919,'Euml'=>203,
            'Gamma'=>915,'Iacute'=>205,'Icirc'=>206,'Igrave'=>204,'Iota'=>921,'Iuml'=>207,'Kappa'=>922,'Lambda'=>923,'Mu'=>924,'Ntilde'=>209,
            'Nu'=>925,'OElig'=>338,'Oacute'=>211,'Ocirc'=>212,'Ograve'=>210,'Omega'=>937,'Omicron'=>927,'Oslash'=>216,'Otilde'=>213,'Ouml'=>214,
            'Phi'=>934,'Pi'=>928,'Prime'=>8243,'Psi'=>936,'Rho'=>929,'Scaron'=>352,'Sigma'=>931,'THORN'=>222,'Tau'=>932,'Theta'=>920,'Uacute'=>218,
            'Ucirc'=>219,'Ugrave'=>217,'Upsilon'=>933,'Uuml'=>220,'Xi'=>926,'Yacute'=>221,'Yuml'=>376,'Zeta'=>918,'aacute'=>225,'acirc'=>226,
            'acute'=>180,'aelig'=>230,'agrave'=>224,'alefsym'=>8501,'alpha'=>945,'amp'=>38,'and'=>8743,'ang'=>8736,'apos'=>39,'aring'=>229,'asymp'=>8776,
            'atilde'=>227,'auml'=>228,'bdquo'=>8222,'beta'=>946,'brvbar'=>166,'bull'=>8226,'cap'=>8745,'ccedil'=>231,'cedil'=>184,'cent'=>162,'chi'=>967,
            'circ'=>710,'clubs'=>9827,'cong'=>8773,'copy'=>169,'crarr'=>8629,'cup'=>8746,'curren'=>164,'dArr'=>8659,'dagger'=>8224,'darr'=>8595,
            'deg'=>176,'delta'=>948,'diams'=>9830,'divide'=>247,'eacute'=>233,'ecirc'=>234,'egrave'=>232,'empty'=>8709,'emsp'=>8195,'ensp'=>8194,
            'epsilon'=>949,'equiv'=>8801,'eta'=>951,'eth'=>240,'euml'=>235,'euro'=>8364,'exist'=>8707,'fnof'=>402,'forall'=>8704,'frac12'=>189,
            'frac14'=>188,'frac34'=>190,'frasl'=>8260,'gamma'=>947,'ge'=>8805,'gt'=>62,'hArr'=>8660,'harr'=>8596,'hearts'=>9829,'hellip'=>8230,
            'iacute'=>237,'icirc'=>238,'iexcl'=>161,'igrave'=>236,'image'=>8465,'infin'=>8734,'int'=>8747,'iota'=>953,'iquest'=>191,'isin'=>8712,
            'iuml'=>239,'kappa'=>954,'lArr'=>8656,'lambda'=>955,'lang'=>9001,'laquo'=>171,'larr'=>8592,'lceil'=>8968,'ldquo'=>8220,'le'=>8804,
            'lfloor'=>8970,'lowast'=>8727,'loz'=>9674,'lrm'=>8206,'lsaquo'=>8249,'lsquo'=>8216,'lt'=>60,'macr'=>175,'mdash'=>8212,'micro'=>181,
            'middot'=>183,'minus'=>8722,'mu'=>956,'nabla'=>8711,'nbsp'=>160,'ndash'=>8211,'ne'=>8800,'ni'=>8715,'not'=>172,'notin'=>8713,'nsub'=>8836,
            'ntilde'=>241,'nu'=>957,'oacute'=>243,'ocirc'=>244,'oelig'=>339,'ograve'=>242,'oline'=>8254,'omega'=>969,'omicron'=>959,'oplus'=>8853,
            'or'=>8744,'ordf'=>170,'ordm'=>186,'oslash'=>248,'otilde'=>245,'otimes'=>8855,'ouml'=>246,'para'=>182,'part'=>8706,'permil'=>8240,
            'perp'=>8869,'phi'=>966,'pi'=>960,'piv'=>982,'plusmn'=>177,'pound'=>163,'prime'=>8242,'prod'=>8719,'prop'=>8733,'psi'=>968,'quot'=>34,
            'rArr'=>8658,'radic'=>8730,'rang'=>9002,'raquo'=>187,'rarr'=>8594,'rceil'=>8969,'rdquo'=>8221,'real'=>8476,'reg'=>174,'rfloor'=>8971,
            'rho'=>961,'rlm'=>8207,'rsaquo'=>8250,'rsquo'=>8217,'sbquo'=>8218,'scaron'=>353,'sdot'=>8901,'sect'=>167,'shy'=>173,'sigma'=>963,
            'sigmaf'=>962,'sim'=>8764,'spades'=>9824,'sub'=>8834,'sube'=>8838,'sum'=>8721,'sup1'=>185,'sup2'=>178,'sup3'=>179,'sup'=>8835,
            'supe'=>8839,'szlig'=>223,'tau'=>964,'there4'=>8756,'theta'=>952,'thetasym'=>977,'thinsp'=>8201,'thorn'=>254,'tilde'=>732,'times'=>215,
            'trade'=>8482,'uArr'=>8657,'uacute'=>250,'uarr'=>8593,'ucirc'=>251,'ugrave'=>249,'uml'=>168,'upsih'=>978,'upsilon'=>965,'uuml'=>252,
            'weierp'=>8472,'xi'=>958,'yacute'=>253,'yen'=>165,'yuml'=>255,'zeta'=>950,'zwj'=>8205,'zwnj'=>8204),

        // translate table 'unicode ord' => 'windows-1250 chars'
        $unicode_to_CP1250 = array(160=>"\240",161=>"!",162=>"c",163=>"lb",164=>"\244",165=>"yen",166=>"\246",167=>"\247",168=>"\250",169=>"\251",
            170=>"a",171=>"\253",172=>"\254",173=>"\255",174=>"\256",176=>"\260",177=>"\261",178=>"^2",179=>"^3",180=>"\264",181=>"\265",182=>"\266",
            183=>"\267",184=>"\270",185=>"^1",186=>"o",187=>"\273",188=>" 1/4 ",189=>" 1/2 ",190=>" 3/4 ",191=>"?",192=>"`A",193=>"\301",194=>"\302",
            195=>"~A",196=>"\304",197=>"A",198=>"AE",199=>"\307",200=>"`E",201=>"\311",202=>"^E",203=>"\313",204=>"`I",205=>"\315",206=>"\316",207=>"\"I",
            208=>"D",209=>"~N",210=>"`O",211=>"\323",212=>"\324",213=>"~O",214=>"\326",215=>"\327",216=>"O",217=>"`U",218=>"\332",219=>"^U",220=>"\334",
            221=>"\335",222=>"Th",223=>"\337",224=>"`a",225=>"\341",226=>"\342",227=>"~a",228=>"\344",229=>"a",230=>"ae",231=>"\347",232=>"`e",233=>"\351",
            234=>"^e",235=>"\353",236=>"`i",237=>"\355",238=>"\356",239=>"\"i",240=>"d",241=>"~n",242=>"`o",243=>"\363",244=>"\364",245=>"~o",246=>"\366",
            247=>"\367",248=>"o",249=>"`u",250=>"\372",251=>"^u",252=>"\374",253=>"\375",254=>"th",255=>"\"y",256=>"A",257=>"a",258=>"\303",259=>"\343",
            260=>"\245",261=>"\271",262=>"\306",263=>"\346",264=>"^C",265=>"^c",266=>"C",267=>"c",268=>"\310",269=>"\350",270=>"\317",271=>"\357",272=>"\320",
            273=>"\360",274=>"E",275=>"e",276=>"E",277=>"e",278=>"E",279=>"e",280=>"\312",281=>"\352",282=>"\314",283=>"\354",284=>"^G",285=>"^g",286=>"G",
            287=>"g",288=>"G",289=>"g",290=>"G",291=>"g",292=>"^H",293=>"^h",294=>"H",295=>"h",296=>"~I",297=>"~i",298=>"I",299=>"i",300=>"I",301=>"i",
            302=>"I",303=>"i",304=>"I",305=>"i",306=>"IJ",307=>"ij",308=>"^J",309=>"^j",310=>"K",311=>"k",313=>"\305",314=>"\345",315=>"L",316=>"l",
            317=>"\274",318=>"\276",319=>"L",320=>"l",321=>"\243",322=>"\263",323=>"\321",324=>"\361",325=>"N",326=>"n",327=>"\322",328=>"\362",329=>"'n",
            332=>"O",333=>"o",334=>"O",335=>"o",336=>"\325",337=>"\365",338=>"OE",339=>"oe",340=>"\300",341=>"\340",342=>"R",343=>"r",344=>"\330",345=>"\370",
            346=>"\214",347=>"\234",348=>"^S",349=>"^s",350=>"\252",351=>"\272",352=>"\212",353=>"\232",354=>"\336",355=>"\376",356=>"\215",357=>"\235",
            358=>"T",359=>"t",360=>"~U",361=>"~u",362=>"U",363=>"u",364=>"U",365=>"u",366=>"\331",367=>"\371",368=>"\333",369=>"\373",370=>"U",371=>"u",
            372=>"^W",373=>"^w",374=>"^Y",375=>"^y",376=>"\"Y",377=>"\217",378=>"\237",379=>"\257",380=>"\277",381=>"\216",382=>"\236",383=>"s",402=>"f",
            452=>"D\216",453=>"D\236",454=>"d\236",455=>"LJ",456=>"Lj",457=>"lj",458=>"NJ",459=>"Nj",460=>"nj",497=>"DZ",498=>"Dz",499=>"dz",536=>"S",
            537=>"s",538=>"T",539=>"t",697=>"\264",698=>"\264\264",699=>"\221",700=>"\222",701=>"'",710=>"^",711=>"\241",712=>"'",714=>"\264",715=>"`",
            717=>"_",728=>"\242",729=>"\377",731=>"\262",732=>"~",733=>"\275",7682=>"B",7683=>"b",7690=>"D",7691=>"d",7710=>"F",7711=>"f",7744=>"M",7745=>"m",
            7766=>"P",7767=>"p",7776=>"S",7777=>"s",7786=>"T",7787=>"t",7808=>"`W",7809=>"`w",7810=>"\264W",7811=>"\264w",7812=>"\"W",7813=>"\"w",7922=>"`Y",
            7923=>"`y",8194=>" ",8195=>" ",8196=>" ",8197=>" ",8198=>" ",8200=>" ",8201=>" ",8202=>" ",8208=>"-",8209=>"-",8210=>"-",8211=>"\226",8212=>"\227",
            8213=>"-",8216=>"\221",8217=>"\222",8218=>"\202",8219=>"'",8220=>"\223",8221=>"\224",8222=>"\204",8223=>"\"",8224=>"\206",8225=>"\207",
            8226=>"\225",8228=>".",8229=>"..",8230=>"\205",8240=>"\211",8242=>"\264",8243=>"\264\264",8244=>"\264\264\264",8249=>"\213",8250=>"\233",
            8252=>"!!",8260=>"/",8263=>"??",8264=>"?!",8265=>"!?",8279=>"\264\264\264\264",8360=>"Rs",8364=>"\200",8448=>"a/c",8449=>"a/s",8450=>"C",
            8451=>"\260C",8453=>"c/o",8454=>"c/u",8457=>"\260F",8458=>"g",8459=>"H",8460=>"H",8461=>"H",8462=>"h",8463=>"h",8464=>"I",8465=>"I",8466=>"L",
            8467=>"l",8469=>"N",8470=>"No",8473=>"P",8474=>"Q",8475=>"R",8476=>"R",8477=>"R",8481=>"TEL",8482=>"\231",8484=>"Z",8486=>"Ohm",8488=>"Z",
            8492=>"B",8493=>"C",8494=>"e",8495=>"e",8496=>"E",8497=>"F",8499=>"M",8500=>"o",8505=>"i",8507=>"FAX",8517=>"D",8518=>"d",8519=>"e",8520=>"i",
            8521=>"j",8531=>" 1/3 ",8532=>" 2/3 ",8533=>" 1/5 ",8534=>" 2/5 ",8535=>" 3/5 ",8536=>" 4/5 ",8537=>" 1/6 ",8538=>" 5/6 ",8539=>" 1/8 ",
            8540=>" 3/8 ",8541=>" 5/8 ",8542=>" 7/8 ",8543=>" 1/",8544=>"I",8545=>"II",8546=>"III",8547=>"IV",8548=>"V",8549=>"VI",8550=>"VII",8551=>"VIII",
            8552=>"IX",8553=>"X",8554=>"XI",8555=>"XII",8556=>"L",8557=>"C",8558=>"D",8559=>"M",8560=>"i",8561=>"ii",8562=>"iii",8563=>"iv",8564=>"v",
            8565=>"vi",8566=>"vii",8567=>"viii",8568=>"ix",8569=>"x",8570=>"xi",8571=>"xii",8572=>"l",8573=>"c",8574=>"d",8575=>"m",8592=>"<-",8593=>"^",
            8594=>"->",8595=>"V",8596=>"<->",8656=>"<=",8658=>"=>",8660=>"<=>",8722=>"-",8725=>"/",8726=>"\\",8727=>"*",8729=>"\225",8739=>"|",8758=>":",
            8764=>"~",8800=>"/=",8804=>"<=",8805=>">=",8810=>"<<",8811=>">>",8901=>"\267",8920=>"<<<",8921=>">>>",8943=>"\267\267\267"),

        $utf;



    /**
     * Decode entities
     *
     * @param string   text with entities
     * @param string   character set for output
     * @return string  decoded text
     */
    function decode($text, $charset = 'UTF-8')
    {
        $this->utf = $charset == 'UTF-8';

        // decode entities
        return preg_replace_callback(
            '#&([a-z]+|\\#x[0-9a-f]+|\\#[0-9]+);#i',
            array(&$this, '_entity'),
            $text
        );
    }




    /**
     * Callback for preg_replace_callback()
     *
     * @private
     * @param array    matched entity
     * @return string  decoded entity
     */
    function _entity($matches)
    {
        list($match, $entity) = $matches;

        // determine unicode ordinal code
        if ($entity{0} !== '#') { // named entity
            if (!isset($this->entity_to_unicode[$entity]))
                return $match; // unknown named entity

            $ord = $this->entity_to_unicode[$entity];

        } else {
            $ord = ($entity{1} == 'x')
                 ? hexdec(substr($entity, 2))
                 : (int) substr($entity, 1);
        }

        if ($ord<128)  // ASCII
            return chr($ord);

        if ($this->utf) {
            if ($ord<2048) return chr(($ord>>6)+192) . chr(($ord&63)+128);
            if ($ord<65536) return chr(($ord>>12)+224) . chr((($ord>>6)&63)+128) . chr(($ord&63)+128);
            if ($ord<2097152) return chr(($ord>>18)+240) . chr((($ord>>12)&63)+128) . chr((($ord>>6)&63)+128) . chr(($ord&63)+128);
            return $match; // invalid entity
        }

        if (isset($this->unicode_to_CP1250[$ord]))
            return $this->unicode_to_CP1250[$ord];

        return ''; // can't convert to CP1250
    }


} // TexyHtmlEntity


?>
